﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using mqtttLib;
using mqtttLib.Helper;
using mqtttLib.Messages;
using mqtttLib.Messages.Base;
using NAudio.Wave;
using Server;

namespace Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private MqttClient _commun = null;
        private void button1_Click(object sender, EventArgs e)
        {
            if (_commun == null)
            {
                var log = new LogInfo("log4net.config", "");
                _commun = new MqttClient(ip_txt.Text, 1883, 60, clientId_txt.Text, log);
                _commun.LogEvent += _commun_LogEvent;
                _commun.PublishMessageEvent += _commun_PublishMessageEvent;
                _commun.RestartEvent += _commun_RestartEvent;
            }
            _commun.Connection();
            // bool d = _commun.Login();

        }

        private void _commun_RestartEvent()
        {
            _commun.Stop();
            _commun = null;
            button1_Click(null, null);
        }

        private void _commun_PublishMessageEvent(string topicName, byte[] payload)
        {
            var dd = _serialize.Deserialize<string>(payload);
            string c = "";
            //  throw new NotImplementedException();
        }

        private void _commun_LogEvent(string title, MqttMessage data)
        {
            if (ckbShow.Checked)
            {
                //if (!(data is PublishMessage))
                {
                    if (txtInfo.InvokeRequired)
                    {
                        //后端线程向主线程记日志
                        Invoke(new Action<string, MqttMessage>(_commun_LogEvent), title, data);
                    }
                    else
                    {
                        //主线程直接记日志

                        if (ckbHex.Checked)
                        {
                            txtInfo.Text += title + data.GetDataBytes().GetHexLog() + "\r\n";
                        }
                        else
                        {
                            txtInfo.Text += title + data.ToJson() + "\r\n";
                        }
                    }
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //SubscribeMessage message = new SubscribeMessage
            //{
            //    FixedHeader = { Qos = Qos.AtLeastOnce }
            //};
            //// subscribe.PacketIdentifier = 12;
            //message.Subscribe("cc", Qos.AtLeastOnce);
            //message.Subscribe("Abv", Qos.AtLeastOnce);
            if (_commun == null)
            {
                MessageBox.Show(@"请先连接");
            }
            else
            {
                bool d = _commun.Subscribe("/KanbanData/ER24", Qos.AtLeastOnce);

            }


        }


        private void button7_Click(object sender, EventArgs e)
        {
            bool d = _commun.UnSubscribe("/KanbanData/ER24");
            string c = "";
        }
        public byte[] GetBytes(string s)
        {
            //ValidateString(s);
            var stringBytes = new List<byte>();
            //int length = GetstringByteCount(s);
            //stringBytes.Add((byte)(length >> 8));
            //stringBytes.Add((byte)(length & 0xFF));
            stringBytes.AddRange(Encoding.UTF8.GetBytes(s));
            return stringBytes.ToArray();
        }

        private readonly ISerialize _serialize = new MqttSerializeJson();
        private void button3_Click(object sender, EventArgs e)
        {
            //byte[] c = new byte[3];
            // int[] c = new int[] { 1, 2 };
            var c =
                "{\"WorkName\":null,\"MaterielS\":null,\"ProduceQueueS\":null,\"ProductionQuantity\":0,\"CurrentSurplus\":0,\"NexttCarType\":null,\"NextCarTypeNumber\":0,\"GuidingImage\":null,\"TopicName\":\"/KanbanData/ER24\",\"Type\":3,\"Qos\":1}";

            if (_commun == null)
            {
                MessageBox.Show(@"请先连接");
            }
            else
            {

                _commun.Push<string>("/KanbanData/ER24", c, Qos.AtLeastOnce, _serialize);
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtInfo.Text = "";
        }


        private IWaveIn waveIn;
        private WaveOut wavePlayer;
        private BufferedWaveProvider audioFileReader;
        ///   
        /// 开始录音  
        ///   
        private void StartRecording()
        {
            if (waveIn != null) return;
            waveIn = new WaveIn { WaveFormat = new WaveFormat(8000, 1) };//设置码率,比如我这8000  ,192000
            waveIn.DataAvailable += waveIn_DataAvailable;
            waveIn.StartRecording();



        }

        private void WavePlayer_PlaybackStopped(object sender, StoppedEventArgs e)
        {
            if (audioFileReader != null)
            {
                // audioFileReader.Dispose();
                audioFileReader = null;
            }
            if (wavePlayer != null)
            {
                wavePlayer.Dispose();
                wavePlayer = null;
            }
        }
        private void _commun_PublishMessage(byte[] buffers)
        {
            audioFileReader.AddSamples(buffers, 0, buffers.Length);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            byte[] buffers = e.Buffer;
            //PublishMessage publish = new PublishMessage
            //{
            //    FixedHeader = { Qos = Qos.AtLeastOnce },
            //    //  PacketIdentifier = 123,
            //    TopicName = "Abv",
            //    Payload = buffers
            //};
            //bool d = _commun.SendAsync(publish);
            //_commun.Push("Abv", buffers, Qos.AtLeastOnce);
            bool d = _commun.Push("Abv", buffers, Qos.AtLeastOnce);
            short s = BitConverter.ToInt16(buffers, 0);//这样采样比较少，反正是int16型的  
            button.Width = Math.Abs(s / 50);
        }


        ///   
        ///   
        /// 停止录音  
        ///   
        private void StopRecording()
        {
            waveIn.StopRecording();
            waveIn.Dispose();
        }
        private void button4_Click(object sender, EventArgs e)
        {
            StartRecording();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            StopRecording();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            wavePlayer = new WaveOut();
            audioFileReader = new BufferedWaveProvider(new WaveFormat(8000, 1));
            wavePlayer.Init(audioFileReader);
            wavePlayer.PlaybackStopped += WavePlayer_PlaybackStopped;
            wavePlayer.Play();
        }

        private void button8_Click(object sender, EventArgs e)
        {
            int[] c = new int[2] { 1, 2 };
            var str = XmlSerializeUtil.Serializer(c);
            var cs = XmlSerializeUtil.Deserialize<int[]>(str);
            string dd = "";
        }

        private void button9_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 8; i++)
            {
                //Thread thread = new Thread(ThreadTest) { IsBackground = true };
                //thread.Start(i);
                var t = Task<int>.Factory.StartNew(new Func<object, int>(test2), i);
                Thread.Sleep(100);
            }
        }


        private int test2(object i)
        {


            var log = new LogInfo("log4net.config", "");
            MqttClient commun = new MqttClient(ip_txt.Text, 1883, 60, clientId_txt.Text + i, log);
            commun.LogEvent += _commun_LogEvent;
            commun.PublishMessageEvent += _commun_PublishMessageEvent;
            commun.Connection();
            bool d = commun.Subscribe("Abv" + i, Qos.AtLeastOnce);



            while (true)
            {
                int[] c = new int[] { 1, 2 };
                commun.Push<int[]>("Abv" + i, c, Qos.AtLeastOnce, _serialize);
                Thread.Sleep(1000);
            }
            return 0;
        }

        /// <summary>
        /// 多线程测试
        /// </summary>
        public void ThreadTest(object i)
        {
            var log = new LogInfo("log4net.config", "");
            MqttClient commun = new MqttClient(ip_txt.Text, 1883, 60, clientId_txt.Text + i, log);
            commun.LogEvent += _commun_LogEvent;
            commun.PublishMessageEvent += _commun_PublishMessageEvent;
            bool d = commun.Subscribe("Abv" + i, Qos.AtLeastOnce);
            while (true)
            {
                int[] c = new int[] { 1, 2 };
                commun.Push<int[]>("Abv" + i, c, Qos.AtLeastOnce, _serialize);

                //   Thread.Sleep(100); 
            }
        }

        private bool _autoState = true;
        private Thread _autoThread;
        private void auto_start_btn_Click(object sender, EventArgs e)
        {

            int num = Convert.ToInt32(AtuoTime_txt.Text);
            _autoState = true;
            _autoThread = new Thread(delegate ()
            {
                int i = 0;
                while (_autoState)
                {
                    var c =
              "{\"WorkName\":null,\"MaterielS\":null,\"ProduceQueueS\":null,\"ProductionQuantity\":0,\"CurrentSurplus\":0,\"NexttCarType\":null,\"NextCarTypeNumber\":0,\"GuidingImage\":null,\"TopicName\":\"/KanbanData/ER24\",\"Type\":3,\"Qos\":1}";

                    if (_commun == null)
                    {
                        button1_Click(null, null);
                        // MessageBox.Show(@"请先连接");
                    }


                    _commun.Push<string>("/KanbanData/ER24", c, Qos.AtLeastOnce, _serialize);

                    //_server.Kanban(txtStation.Text.Trim(), vinS[i]);
                    //   _autoThread.Start();
                    Thread.Sleep(1000 * num);
                }
            })
            {
                IsBackground = true
            };
            _autoThread.Start();

            auto_start_btn.Enabled = false;
            auto_stop_btn.Enabled = true;
        }
    }
}
